"""
标签管理API端点
"""
from __future__ import annotations

from datetime import datetime, timezone
from typing import Dict, List, Optional
from fastapi import APIRouter, Depends, Query
from motor.motor_asyncio import AsyncIOMotorDatabase
from bson import ObjectId

from app.core.database import get_database
from app.core.response import success_response, error_response, ErrorTypes, ApiResponse, paginated_response
from app.api.deps import get_current_user
from app.models.user import User
from app.models.tag import TagCreate, TagUpdate, TagResponse, TagFilter

router = APIRouter()

# 支持的模块类型
SUPPORTED_MODULE_TYPES = [
    "project", "requirement", "task", "defect", "test_case",
    "document", "version", "user", "comment", "notification"
]

@router.get("/list", response_model=ApiResponse, summary="获取标签列表")
async def get_tags(
    module_type: Optional[str] = Query(None, description="模块类型筛选"),
    search: Optional[str] = Query(None, description="搜索关键词"),
    include_system: bool = Query(True, description="是否包含系统标签"),
    page: int = Query(1, ge=1, description="页码"),
    page_size: int = Query(50, ge=1, le=200, description="每页数量"),
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """获取标签列表（支持模块筛选）"""
    try:
        # 构建查询条件
        query: Dict[str, any] = {}
        
        # 模块类型筛选
        if module_type:
            if module_type not in SUPPORTED_MODULE_TYPES and module_type != "all":
                return error_response(
                    error_type=ErrorTypes.VALIDATION_ERROR,
                    message=f"不支持的模块类型: {module_type}"
                )
            if module_type != "all":
                query["module_type"] = module_type
        
        # 系统标签筛选
        if not include_system:
            query["is_system"] = {"$ne": True}
        
        # 搜索关键词筛选
        if search:
            query["$or"] = [
                {"name": {"$regex": search, "$options": "i"}},
                {"description": {"$regex": search, "$options": "i"}}
            ]
        
        # 计算总数
        total = await db.tags.count_documents(query)
        
        # 分页查询
        skip = (page - 1) * page_size
        cursor = db.tags.find(query).sort("name", 1).skip(skip).limit(page_size)
        tags = await cursor.to_list(length=None)
        
        # 转换为响应格式
        tag_responses: List[TagResponse] = []
        for tag in tags:
            tag_response = TagResponse(
                id=str(tag["_id"]),
                name=tag["name"],
                color=tag.get("color", "#1890ff"),
                description=tag.get("description"),
                module_type=tag.get("module_type"),
                usage_count=tag.get("usage_count", 0),
                is_system=tag.get("is_system", False),
                created_at=tag.get("created_at"),
                updated_at=tag.get("updated_at")
            )
            tag_responses.append(tag_response)
        
        return success_response(
            data={
                "items": tag_responses,
                "total": total,
                "page": page,
                "page_size": page_size
            },
            message="获取标签列表成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取标签列表失败: {str(e)}"
        )

@router.get("/module/{module_type}", response_model=ApiResponse, summary="获取模块标签列表")
async def get_module_tags(
    module_type: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """获取指定模块的标签列表（不分页，用于下拉选择）"""
    try:
        if module_type not in SUPPORTED_MODULE_TYPES:
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message=f"不支持的模块类型: {module_type}"
            )
        
        # 查询该模块的标签或通用标签（module_type为None）
        query = {
            "$or": [
                {"module_type": module_type},
                {"module_type": None},
                {"module_type": {"$exists": False}}
            ],
            "is_system": {"$ne": True}
        }
        
        cursor = db.tags.find(query).sort("name", 1)
        tags = await cursor.to_list(length=None)
        
        # 转换为响应格式
        tag_responses: List[TagResponse] = []
        for tag in tags:
            tag_response = TagResponse(
                id=str(tag["_id"]),
                name=tag["name"],
                color=tag.get("color", "#1890ff"),
                description=tag.get("description"),
                module_type=tag.get("module_type"),
                usage_count=tag.get("usage_count", 0),
                is_system=tag.get("is_system", False),
                created_at=tag.get("created_at"),
                updated_at=tag.get("updated_at")
            )
            tag_responses.append(tag_response)
        
        return success_response(
            data=tag_responses,
            message="获取模块标签列表成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取模块标签列表失败: {str(e)}"
        )

@router.get("/detail/{tag_id}", response_model=ApiResponse, summary="获取标签详情")
async def get_tag(
    tag_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """获取标签详情"""
    try:
        # 验证ID格式
        if not ObjectId.is_valid(tag_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的标签ID格式"
            )
        
        # 查询标签
        tag = await db.tags.find_one({"_id": ObjectId(tag_id)})
        
        if not tag:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的标签"
            )
        
        # 转换为响应格式
        tag_response = TagResponse(
            id=str(tag["_id"]),
            name=tag["name"],
            color=tag.get("color", "#1890ff"),
            description=tag.get("description"),
            module_type=tag.get("module_type"),
            usage_count=tag.get("usage_count", 0),
            is_system=tag.get("is_system", False),
            created_at=tag.get("created_at"),
            updated_at=tag.get("updated_at")
        )
        
        return success_response(
            data=tag_response,
            message="获取标签详情成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"获取标签详情失败: {str(e)}"
        )

@router.post("/create", response_model=ApiResponse, summary="创建标签")
async def create_tag(
    tag: TagCreate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """创建标签"""
    try:
        # 检查名称是否已存在（同一模块内名称唯一）
        query = {"name": tag.name}
        if tag.module_type:
            query["module_type"] = tag.module_type
        else:
            query["$or"] = [
                {"module_type": None},
                {"module_type": {"$exists": False}}
            ]
        
        existing = await db.tags.find_one(query)
        
        if existing:
            module_info = f"（模块: {tag.module_type}）" if tag.module_type else "（通用标签）"
            return error_response(
                error_type=ErrorTypes.CONFLICT_ERROR,
                message=f"标签名称 '{tag.name}' 在该模块已存在{module_info}"
            )
        
        # 验证模块类型
        if tag.module_type and tag.module_type not in SUPPORTED_MODULE_TYPES:
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message=f"不支持的模块类型: {tag.module_type}"
            )
        
        # 准备数据
        # 标签管理模块创建的标签都是系统标签
        now = datetime.now(timezone.utc)
        tag_data = {
            "name": tag.name,
            "color": tag.color or "#1890ff",
            "description": tag.description,
            "module_type": tag.module_type,
            "usage_count": 0,
            "is_system": True,  # 标签管理模块创建的标签都是系统标签
            "created_at": now,
            "updated_at": now
        }
        
        # 插入数据
        result = await db.tags.insert_one(tag_data)
        
        # 获取创建的标签
        created_tag = await db.tags.find_one({"_id": result.inserted_id})
        
        if not created_tag:
            return error_response(
                error_type=ErrorTypes.INTERNAL_ERROR,
                message="创建标签后无法获取标签数据"
            )
        
        # 转换为响应格式
        tag_response = TagResponse(
            id=str(created_tag["_id"]),
            name=created_tag["name"],
            color=created_tag.get("color", "#1890ff"),
            description=created_tag.get("description"),
            module_type=created_tag.get("module_type"),
            usage_count=created_tag.get("usage_count", 0),
            is_system=created_tag.get("is_system", False),
            created_at=created_tag.get("created_at"),
            updated_at=created_tag.get("updated_at")
        )
        
        return success_response(
            data=tag_response,
            message="创建标签成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"创建标签失败: {str(e)}"
        )

@router.put("/update/{tag_id}", response_model=ApiResponse, summary="更新标签")
async def update_tag(
    tag_id: str,
    tag: TagUpdate,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """更新标签"""
    try:
        # 验证ID格式
        if not ObjectId.is_valid(tag_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的标签ID格式"
            )
        
        # 查询标签
        existing = await db.tags.find_one({"_id": ObjectId(tag_id)})
        
        if not existing:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的标签"
            )
        
        # 如果更新名称或模块类型，检查是否与其他标签冲突
        new_module_type = tag.module_type if tag.module_type is not None else existing.get("module_type")
        if (tag.name and tag.name != existing["name"]) or (tag.module_type is not None and tag.module_type != existing.get("module_type")):
            query = {
                "_id": {"$ne": ObjectId(tag_id)},
                "name": tag.name if tag.name else existing["name"]
            }
            if new_module_type:
                query["module_type"] = new_module_type
            else:
                query["$or"] = [
                    {"module_type": None},
                    {"module_type": {"$exists": False}}
                ]
            
            name_conflict = await db.tags.find_one(query)
            
            if name_conflict:
                module_info = f"（模块: {new_module_type}）" if new_module_type else "（通用标签）"
                return error_response(
                    error_type=ErrorTypes.CONFLICT_ERROR,
                    message=f"标签名称 '{tag.name or existing['name']}' 在该模块已存在{module_info}"
                )
        
        # 验证模块类型
        if tag.module_type and tag.module_type not in SUPPORTED_MODULE_TYPES:
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message=f"不支持的模块类型: {tag.module_type}"
            )
        
        # 准备更新数据
        update_data: Dict[str, any] = {}
        if tag.name is not None:
            update_data["name"] = tag.name
        if tag.color is not None:
            update_data["color"] = tag.color
        if tag.description is not None:
            update_data["description"] = tag.description
        if tag.module_type is not None:
            update_data["module_type"] = tag.module_type
        
        update_data["updated_at"] = datetime.now(timezone.utc)
        
        # 更新数据
        result = await db.tags.update_one(
            {"_id": ObjectId(tag_id)},
            {"$set": update_data}
        )
        
        if result.modified_count == 0:
            return error_response(
                error_type=ErrorTypes.INTERNAL_ERROR,
                message="更新标签失败"
            )
        
        # 获取更新后的标签
        updated_tag = await db.tags.find_one({"_id": ObjectId(tag_id)})
        
        if not updated_tag:
            return error_response(
                error_type=ErrorTypes.INTERNAL_ERROR,
                message="更新标签后无法获取标签数据"
            )
        
        # 转换为响应格式
        tag_response = TagResponse(
            id=str(updated_tag["_id"]),
            name=updated_tag["name"],
            color=updated_tag.get("color", "#1890ff"),
            description=updated_tag.get("description"),
            module_type=updated_tag.get("module_type"),
            usage_count=updated_tag.get("usage_count", 0),
            is_system=updated_tag.get("is_system", False),
            created_at=updated_tag.get("created_at"),
            updated_at=updated_tag.get("updated_at")
        )
        
        return success_response(
            data=tag_response,
            message="更新标签成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"更新标签失败: {str(e)}"
        )

@router.delete("/delete/{tag_id}", response_model=ApiResponse, summary="删除标签")
async def delete_tag(
    tag_id: str,
    db: AsyncIOMotorDatabase = Depends(get_database),
    current_user: User = Depends(get_current_user)
) -> Dict:
    """删除标签"""
    try:
        from bson import ObjectId
        
        # 验证ID格式
        if not ObjectId.is_valid(tag_id):
            return error_response(
                error_type=ErrorTypes.VALIDATION_ERROR,
                message="无效的标签ID格式"
            )
        
        # 查询标签
        tag = await db.tags.find_one({"_id": ObjectId(tag_id)})
        
        if not tag:
            return error_response(
                error_type=ErrorTypes.NOT_FOUND,
                message="未找到指定的标签"
            )
        
        # 删除标签
        await db.tags.delete_one({"_id": ObjectId(tag_id)})
        
        return success_response(
            data={"id": tag_id},
            message="删除标签成功"
        )
        
    except Exception as e:
        return error_response(
            error_type=ErrorTypes.INTERNAL_ERROR,
            message=f"删除标签失败: {str(e)}"
        )